#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class DtLockableObject
{
public:
	DtLockableObject(void) {}
	virtual ~DtLockableObject(void) {}
	
	/// Lock an object. 
	virtual void Lock() = 0;

	/// Unlock an object. 
	virtual void Unlock() = 0;
};

class DtCriticalSection : public DtLockableObject
{
public:
	
	DtCriticalSection() 
	{ 
		m_CritSect.SpinCount = 4000;
		InitializeCriticalSection(&m_CritSect); 
	};
	inline virtual ~DtCriticalSection() 
	{ 
		DeleteCriticalSection(&m_CritSect); 
	};

	/// Lock the critical section. 
	__inline virtual void Lock() 
	{ 
		EnterCriticalSection(&m_CritSect); 
	};

	/// Unlock the critical section. 
	__inline virtual void Unlock() 
	{ 
		LeaveCriticalSection(&m_CritSect); 
	};

	/// tries to enter the critical section, if not successful it returns false.
	/*
	__inline virtual bool TryLock() 
	{ 
		return TryEnterCriticalSection(&m_CritSect) != 0; 
	};
	*/
private:
	CRITICAL_SECTION m_CritSect;
};

class DtLock
{
public:
 
	/// The DtLock constructor automaticly locks a lockable object unless otherwise specified. 
	/// @param pLockable The object that we should lock
	/// @param InitalLock Default true, set to false if you dont want to lock the object from start.
	DtLock(DtLockableObject* pLockable, bool bInitialLock = true)
	{
		m_pLockable = pLockable;
		
		//If we want to lock directly
		if (bInitialLock)
			m_pLockable->Lock();
	};

	/// The DtLock constructor automaticly locks a lockable object unless otherwise specified. 
	/// @param pLockable The object that we should lock
	/// @param InitalLock Default true, set to false if you dont want to lock the object from start.
	DtLock(DtLockableObject& Lockable, bool bInitialLock = true)
	{
		m_pLockable = &Lockable;

		//If we want to lock directly
		if (bInitialLock)
			m_pLockable->Lock();
	};

	/// The destructor unlocks the object.
	~DtLock()
	{
		m_pLockable->Unlock();
	};


	/// Lock the object. 
	__inline void Lock()
	{
		m_pLockable->Lock();
	};
	
	/// Unlock the object. 
	__inline void Unlock()
	{
		m_pLockable->Unlock();
	};


private:

	/// Pointer to the lockable object
	DtLockableObject* m_pLockable;
   
};